import * as path from 'path';
import * as fs from 'fs';
import { exec } from "child_process";


export default class PathUtils {

    /** 编辑器安装资源目录 */
    static pathEditorAppResRoot = Editor.App.path.substr(0, Editor.App.path.indexOf('app.asar') - 1);

    /** 项目根目录 */
    static pathProject = Editor.Project.path;
    static getPathInProject(pathName: string) {
        return path.join(Editor.Project.path, pathName);
    }

    /** 项目资源目录 */
    static pathAssets = path.join(Editor.Project.path, 'assets');
    static getPathInAssets(pathName: string) {
        return path.join(PathUtils.pathAssets, pathName);
    }

    /** 项目框架目录 */
    static pathFramework = path.join(Editor.Project.path, 'assets', 'framework');
    static getPathInFramework(pathName: string) {
        return path.join(PathUtils.pathFramework, pathName);
    }

    /** 项目编译模板目录 */
    static pathBuildTemplates = path.join(Editor.Project.path, 'build-templates');
    static getPathInBuildTemplates(pathName: string) {
        return path.join(PathUtils.pathBuildTemplates, pathName);
    }

    /** 项目编译目录 */
    static pathBuild = path.join(Editor.Project.path, 'build');
    static getPathInBuild(pathName: string) {
        return path.join(PathUtils.pathBuild, pathName);
    }




    /** 插件根目录 */
    static pathPackageRoot = path.join(__dirname, '..', '..').replace('/dist', '');
    static getPathInPackage(pathName: string) {
        return path.join(PathUtils.pathPackageRoot, pathName);
    }

    /** 插件运行时文件目录 */
    static pathPackageRuntimeAssets = path.join(__dirname, '..', '..', 'runtime-assets').replace('/dist', '');
    static getPathInPackageRuntime(pathName: string) {
        return path.join(PathUtils.pathPackageRuntimeAssets, pathName);
    }

    /** 插件资源目录 */
    static pathTemplateAssets = path.join(__dirname, '..', '..', 'templates', 'assets-template').replace('/dist', '');
    static getPathInTemplateAssets(pathName: string) {
        return path.join(PathUtils.pathTemplateAssets, pathName);
    }

    /** 插件框架目录 */
    static pathTemplateFramework = path.join(__dirname, '..', '..', 'templates', 'framework-template').replace('/dist', '');
    static getPathInTemplateFramework(pathName: string) {
        return path.join(PathUtils.pathTemplateFramework, pathName);
    }

    /** 插件编译模板目录 */
    static pathInTemplateBuild = path.join(__dirname, '..', '..', 'templates', 'build-templates-template').replace('/dist', '');
    static getPathInTemplateBuild(pathName: string) {
        return path.join(PathUtils.pathInTemplateBuild, pathName);
    }

    /** 插件编辑器模板目录 */
    static pathInTemplateEditor = path.join(__dirname, '..', '..', 'templates', 'editor-template').replace('/dist', '');
    static getPathInTemplateEditor(pathName: string) {
        return path.join(PathUtils.pathInTemplateEditor, pathName);
    }


    /** 插件工具目录 */
    static pathPackageTools = path.join(__dirname, '..', '..', 'tools').replace('/dist', '');
    static getPathInPackageTools(pathName: string) {
        return path.join(PathUtils.pathPackageTools, pathName);
    }


    /**
     * 格式化路径
     * @param {string} filePath 路径
     * @param {string} splitChar 分隔符
     */
    static formatPath(filePath: string, splitChar: string) {
        const dirs = filePath.split(splitChar || '/');
        return path.join(...dirs);
    };


    /**
     * 创建文件夹
     * @param {*} dirPath 路径
     * @param {*} mode 
     */
    static mkPathSync(dirPath: string, mode?: any){
        try {
            if (!fs.existsSync(dirPath)) {
                console.log('[tool-box]Creator ' + dirPath + ' path...');

                let pathtmp: string;
                dirPath.split(/[/\\]/).forEach((dirname)=>{
                    if (pathtmp) {
                        pathtmp = path.join(pathtmp, dirname);
                    } else {
                        pathtmp = dirname;
                    }

                    if (pathtmp !== '' && !fs.existsSync(pathtmp)) {
                        if (!fs.mkdirSync(pathtmp, mode)) {
                            return false;
                        }
                    }
                });
            }
            return true;
        } catch (e) {
            console.error("create path fail! path=" + dirPath +" errorMsg:" + e);
            return false;
        }
    };


    /**
     * 创建assets文件夹
     * @param {string} dirPath 从Assets根目录开始的路径
     * @param {*} callback 回调
     */
    static mkdirsSyncInAssets = async (dirPath: string, callback?: Function)=>{
        try {
            if (!fs.existsSync(`${PathUtils.pathAssets}/${dirPath}`)) {
                console.log('[tool-box]Creator ' + dirPath + ' path...');

                const paths = dirPath.split(/[/\\]/);
                const createDir: Function = async (pathtmp: string)=>{
                    if (!fs.existsSync(`${PathUtils.pathAssets}/${pathtmp}`)) {
                        
                        await Editor.Message.request('asset-db', 'create-asset', `db://assets/${pathtmp}`, null, {});
                        paths.splice(0, 1);
                         // 递归创建文件夹
                        if (paths[0]) { return await createDir(path.join(pathtmp, paths[0])); }
                        console.log('[tool-box]Creator ' + pathtmp + ' path successed!')
                        
                        callback && callback();
                        return;
                    } else {
                        paths.splice(0, 1);
                        // 递归创建文件夹
                        if (paths[0]) { return await createDir(path.join(pathtmp, paths[0])); }
                    }
                };

                if (paths[0]) { return await createDir(paths[0]); }
            } else {
                console.log('[tool-box]' + dirPath + ' exists!');
                callback && callback();
            }
        } catch (e) {
            console.error("create path fail! path=" + dirPath +" errorMsg:" + e);
        }
    };

    
    /**
     * 刷新编辑器目录
     * @param assetsdbPath db://开头的路径
     */
    static async refreshAsset(assetsdbPath: string) {
        return await Editor.Message.request('asset-db', 'refresh-asset', assetsdbPath);
    }




    /**
     * 文件遍历方法
     * @param filePath 需要遍历的文件路径
     * @param needFile 需要遍历的文件格式(png，js, ts, jpg, json...)
     * @param isNotRecursion 是否不进行递归
     */
    static dumpAllFiles(filePath: string, needFile?: string, isNotRecursion?: boolean){
        let result: any = [];

        // 根据文件路径读取文件，返回文件列表
        try {
            const filePaths = fs.readdirSync(filePath);
            let filedir, stats;

            // 遍历读取到的文件列表
            filePaths.forEach((filename: string)=>{
                // 获取当前文件的绝对路径
                filedir = path.join(filePath, filename);

                try {
                    // 根据文件路径获取文件信息，返回一个fs.Stats对象
                    stats = fs.statSync(filedir);
                    if(stats.isFile()){
                        if (needFile && path.extname(filename) !== `.${needFile}`) {
                        } else {
                            result.push(filedir);    
                        }
                    } else if(!isNotRecursion && stats.isDirectory()){
                        // 递归，如果是文件夹，就继续遍历该文件夹下面的文件
                        result = [...result, ...PathUtils.dumpAllFiles(filedir, needFile, isNotRecursion)];
                    }
                } catch(err) {
                    console.warn('获取文件stats失败:', filedir, err);
                }
            });
        } catch (error) {
            console.error(error);
        }

        return result;
    };

    /**
     * 拷贝文件夹
     * @param {*} srcDir 要拷贝的文件夹
     * @param {*} destDir 存放目录
     */
    static copyDirs = (srcDir: string, destDir: string, callback?: Function)=>{
        console.log('[tool-box]mkdirs:', destDir);
        PathUtils.mkPathSync(destDir);

        console.log('[tool-box]copy:', srcDir, destDir);
        const sh = `cp -rf ${srcDir} ${destDir}`;
        exec(sh, (err: any, stdout: any, stderr: any) => {
            if (err || stderr) { return console.log('[tool-box]copy failed', err, stderr); }

            callback && callback();
        });
    };

}


